Files and Streams(I/O)
Variables and arrays offer only temporary storage of data—the data are lost when an object is garbage collected or when the program terminates. By contrast, files are used for long-term storage of large amounts of data and can retain data even after the program that created the data terminates. Data maintained in files often are called persistent data. Computers can store files on secondary storage devices, such as magnetic disks, optical disks and magnetic tapes.
C#’s powerful and abundant file-processing and stream-input/output features. C# uses the I/O system and classes defined by the .NET Framework. C# programs perform I/O through streams. A stream is an abstraction that either produces or consumes information. A stream is linked to a physical device by the C# I/O system.
Byte Streams and Character Streams:
In C#, char is a 16-bit type, and byte is an 8-bit type. If you are using the ASCII character set, then it is easy to convert between char and byte; byte streams are not perfectly suited to handling character-based I/O. To solve this problem, C# defines several classes that convert a byte stream into a character stream, handling the translation of byte-to-char and char-to-byte for you automatically.
Predefined Streams
Three predefined streams, which are exposed through the properties called Console.In, Console.Out, and Console.Error, are available to all programs that use the System namespace.
C# defines both byte and character stream classes. However, the character stream classes are really just wrappers that convert an underlying byte stream into a character stream, handling any conversion automatically. Thus, the character streams, while logically separate, are built upon byte streams.
All stream classes are defined within the System.IO namespace. To use these classes, you will usually include the following statement .
using System.IO;
Stream Class
C#’s streams is System.IO.Stream. Stream represents a byte stream and is a base class for all other stream classes.
Stream class Methods |
|
Method |
Description |
void Close( ) |
Closes the stream. |
void Flush( ) |
Writes the contents of the stream to the physical device. |
int ReadByte( ) |
Returns an integer representation of the next available byte of input. Returns −1 when the end of the fi le is encountered. |
int Read(byte[ ] buf, int offset, int numBytes) |
Attempts to read up to numBytes bytes into buf starting at buf[offset], returning the number of bytes successfully read. |
long Seek(long offset, SeekOrigin origin) |
Sets the current position in the stream to the specifi ed offset from the specifi ed origin. |
void WriteByte(byte b) |
Writes a single byte to an output stream. |
void Write(byte[ ] buf, int offset, int numBytes) |
Writes a subrange of numBytes bytes from the array buf, beginning at buf[offset]. |
Exceptions:
IOException, NotSupportedException
Byte Stream Classes
Stream Class |
Description |
BufferedStream |
Wraps a byte stream and adds buffering. Buffering provides a performance enhancement in many cases. |
Compression.DeflateStream |
Wraps a byte stream and provides for compression/decompression of data. (Added by .NET Framework 2.0.) |
Compression.GZipStream |
Wraps a byte stream and provides for compression/decompression of data. It uses the GZIP format. (Added by .NET Framework 2.0.) |
FileStream |
A byte stream designed for file I/O. |
MemoryStream |
A byte stream that uses memory for storage. |
UnmanagedMemoryStream |
A byte stream that uses memory for storage, but is not suitable for mixed-language programming. (Added by .NET Framework 2.0.) |
Character Stream Wrapper Classes
At the top of the character stream hierarchy are the abstract classes TextReader and TextWriter. TextReader handles input and TextWriter handles output. The methods defined by these two abstract classes are available to all of their subclasses.
TextReader Methods |
|
Method |
Description |
void Close( ) |
Closes the stream. |
int Peek( ) |
Obtains the next character from the input stream, but does not remove that character. Returns –1 if no character is available. |
int Read( ) |
Returns an integer representation of the next available character from the invoking input stream. Returns –1 when the end of the stream is encountered. |
int Read(char[ ] buf, int offset, int numChars) |
Attempts to read up to numChars characters into buf starting at buf[offset], returning the number of characters successfully read. |
int ReadBlock(char[ ] buf, int offset, int numChars) |
Attempts to read up to numChars characters into buf starting at buf[offset], returning the number of characters successfully read. |
string ReadLine( ) |
Reads the next line of text and returns it as a string. Null is returned if an attempt is made to read at end-of-file. |
string ReadToEnd( ) |
Reads all of the remaining characters in a stream and returns them as a string. |
Method |
Description |
void Write(int val) |
Write an int. |
void Write(double val) |
Write a double. |
void Write(bool val) |
Write a bool. |
void WriteLine(string val) |
Write a string followed by a newline. |
void WriteLine(uint val) |
Write a uint followed by a newline. |
Virtual void close() |
closes the stream |
Virtual void flush() |
causes any data remaining in the output buffer to be written to the physical medium. |
The TextReader and TextWriter classes are implemented by several character-based stream classes.
Stream Class |
Description |
StreamReader |
Read characters from a byte stream. This class wraps a byte input stream. |
StreamWriter |
Write characters to a byte stream. This class wraps a byte output stream. |
StringReader |
Read characters from a string. |
StringWriter |
Write characters to a string. |
These streams are called BinaryReader and BinaryWriter.
create a byte-oriented stream attached to a file, you will use the FileStream class. FileStream is derived from Stream and contains all of Stream’s functionality. To create a byte stream linked to a file, create a FileStream object. FileStream defines several constructors.
FileStream(string filename, FileMode mode)
FileStream(string fi lename, FileMode mode, FileAccess how)
The FileMode Values |
|
Value |
Description |
FileMode.Append |
Output is appended to the end of file. |
FileMode.Create |
Creates a new output file. Any preexisting file by the same name will be destroyed. |
FileMode.CreateNew |
Creates a new output file. The file must not already exist. |
FileMode.Open |
Opens a preexisting file. |
FileMode.OpenOrCreate |
Opens a file if it exists, or creates the file if it does not already exist. |
FileMode.Truncate |
Opens a preexisting file, but reduces its length to zero. |
FileAccess Mode
FileAccess.Read |
FileAccess.Write |
FileAccess.ReadWrite |
When you are done with a file, you should close it by calling Close( ).
Reading Bytes from a FileStream
FileStream defines two methods that read bytes from a file: ReadByte( ) and Read( ). To read a single byte from a file, use ReadByte( ).
int ReadByte( )
int Read(byte[ ] buf, int offset, int numBytes)
Exceptions:
NotSupportedException (the stream is not opened for input) and ObjectDisposedException (the stream is closed).
Writing Bytes from a FileStream
To write a byte to a file, use the WriteByte( ) method.
void WriteByte(byte val)
void Write(byte[ ] buf, int offset, int numBytes)
Flush( ): using this method we can release the memory .
Program to read the data from the text file.
using System;
using System.IO;
class Sample
{
public static void Main(string[] args)
{
int i;
FileStream fin;
string fname;
Console.WriteLine("Enter filename");
fname = Console.ReadLine();
// exception handling is not mandatory
try
{
fin = new FileStream(fname , FileMode.Open);
}
catch (FileNotFoundException exc)
{
Console.WriteLine(exc.Message);
return;
}
// read bytes until EOF is encountered
do
{
try
{
i = fin.ReadByte();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
return;
}
if (i != -1) Console.Write((char)i);
} while (i != -1);
fin.Close();
}
}
Program to copy the data from one file to another file
using System;
using System.IO;
class Sample
{
public static void Main(string[] args)
{
FileStream fout,fin;
string fname,fname1;
Console.WriteLine("Enter source filename");
fname = Console.ReadLine();
Console.WriteLine("Enter new filename");
fname1 = Console.ReadLine();
try
{
fin = new FileStream(fname, FileMode.Open);
fout = new FileStream(fname1, FileMode.Create);
}
catch (IOException exc)
{
Console.WriteLine(exc.Message + "\nError Opening Output File");
return;
}
try
{
int i;
do
{
i = fin.ReadByte();
if(i!=-1)
fout.WriteByte((byte)i);
}
while (i != -1);
}
catch (IOException exc)
{
Console.WriteLine(exc.Message + "File Error");
}
fin.Close();
fout.Close();
}
}
Chaaracter based I/O
StreamReader or a StreamWriter. These classes automatically convert a byte stream into a character stream. StreamWriter is derived from TextWriter. StreamReader is derived from TextReader.
Constructors:
StreamWriter(Stream stream)
StreamWriter(string filename)
StreamWriter(string filename, bool appendFlag)
StreamReader(Stream stream)
StreamReader(string filename)
Exceptions
ArgumentNullException
ArgumentException
Program to copy the data from one file to another file using streamreader and streamwriter
using System;
using System.IO;
class Vision
{
public static void Main()
{
string str,str1,s;
StreamReader sr;
FileStream f,f1;
StreamWriter sw;
Console.WriteLine("Etner filename to read");
str = Console.ReadLine();
Console.WriteLine("Enter filename to write");
str1 = Console.ReadLine();
try
{
f = new FileStream(str , FileMode.Open );
f1 = new FileStream(str1, FileMode.Create);
sr = new StreamReader(f);
sw = new StreamWriter(f1);
}
catch (IOException exc)
{
Console.WriteLine(exc.Message + "Cannot open file.");
return;
}
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
sw.WriteLine(s);
}
sr.Close();
sw.Close();
}
}
Reading and Writing Binary Data
BinaryWriter is a wrapper around a byte stream that manages the writing of binary data. To write the data into the file use write () method.
BinaryReader is a wrapper around a byte stream that handles the reading of binary data.To read the data from the file use read () method.
Constructors
BinaryWriter(Stream outputStream)
BinaryReader(Stream inputStream)
outputStream/inputstream is the stream to which data is written/read. To write/read output to a file, you can use the object created by FileStream for this parameter.
Exceptions
EndOfStreamException, ArgumentException, ArgumentNullException
Program on Binaryreader and Binarywriter
using System;
using System.IO;
class Inventory
{
public static void Main()
{
BinaryWriter bw;
BinaryReader br;
string na;
int qty, rate;
try
{
bw = new
BinaryWriter(new FileStream("item.dat",
FileMode.Create));
}
catch (IOException exc)
{
Console.WriteLine(exc.Message + "\nCannot open file.");
return;
}
try
{
bw.Write("rin");
bw.Write(10);
bw.Write(5);
bw.Write("arial");
bw.Write(22);
bw.Write(4);
bw.Write("surf");
bw.Write(15);
bw.Write(7);
bw.Write("nirma");
bw.Write(20);
bw.Write(3);
}
catch (IOException exc)
{
Console.WriteLine(exc.Message );
}
bw.Close();
Console.WriteLine();
try
{
br = new
BinaryReader(new FileStream("item.dat",
FileMode.Open));
}
catch (FileNotFoundException exc)
{
Console.WriteLine(exc.Message + "\nCannot open file.");
return;
}
Console.Write("Enter item to Find: ");
string f = Console.ReadLine();
try
{
for (; ; )
{
na = br.ReadString();
qty = br.ReadInt32();
rate = br.ReadInt32();
if (na.CompareTo(f ) == 0)
{
Console.WriteLine(na + " " + qty + " on hand. " +
"rate: {0:C} each", rate );
Console.WriteLine("Total value of {0}: {1:C}.",
na , qty*rate );
break;
}
}
}
catch (EndOfStreamException)
{
Console.WriteLine("Item not found.");
}
catch (IOException exc)
{
Console.WriteLine(exc.Message);
}
br.Close();
}
}
Random Access Files
sequential files are accessed in a strictly linear fashion, one byte after another. C# also allows you to access the contents of a file in random order. To do this, you will use the Seek( ) method defined by FileStream.
long Seek(long newPos, SeekOrigin origin)
newPos specifies the new position, in bytes
origin will be one of these values
Value |
Meaning |
SeekOrigin.Begin |
Seek from the beginning of the fi le. |
SeekOrigin.Current |
Seek from the current location. |
SeekOrigin.End |
Seek from the end of the fi le. |
Exceptions:
IOException, NotSupportedException
Program on binary writer and reader
using System;
using System.IO;
class Sample
{
public static void Main()
{
FileStream f;
char ch;
try
{
f = new FileStream("random.dat", FileMode.Create);
}
catch (IOException exc)
{
Console.WriteLine(exc.Message);
return;
}
Console.WriteLine("Enter name ");
string s;
s=Console.ReadLine ();
char []b;
b = s.ToCharArray();
for (int i = 0; i < b.Length ; i++)
{
try
{
f.WriteByte((byte)b[i]);
}
catch (IOException exc)
{
Console.WriteLine(exc.Message);
return;
}
}
try
{
f.Seek(0, SeekOrigin.Begin);
ch = (char)f.ReadByte();
Console.WriteLine("First value is " + ch);
f.Seek(1, SeekOrigin.Begin);
ch = (char)f.ReadByte();
Console.WriteLine("Second value is " + ch);
f.Seek(4, SeekOrigin.Begin);
ch = (char)f.ReadByte();
Console.WriteLine("Fifth value is " + ch);
Console.WriteLine();
Console.WriteLine("Given completer String");
for (int i = 0; i < b.Length ; i ++)
{
f.Seek(i, SeekOrigin.Begin);
ch = (char)f.ReadByte();
Console.Write(ch + " ");
}
}
catch (IOException exc)
{
Console.WriteLine(exc.Message);
}
Console.WriteLine();
f.Close();
}
}
MemoryStream
It is used to read input from or to write output to an array, rather than directly from or to a device. To do this, you will use MemoryStream. MemoryStream is an implementation of Stream that uses an array of bytes for input and/or output
MemoryStream(byte[ ] buf)
StringReader and StringWriter
StringReader and StringWriter. StringReader inherits TextReader, and StringWriter inherits TextWriter
StringWriter( )
StringReader(string str)
Program on StringReader and StringWriter
using System;
using System.IO;
class StrRdrDemo
{
public static void Main()
{
StringWriter sw = new StringWriter();
string s;
for (int i = 0; i < 10; i++)
{
s = Console.ReadLine();
sw.WriteLine(s);
}
StringReader sr = new StringReader(sw.ToString());
string str = sr.ReadLine();
while (str != null)
{
str = sr.ReadLine();
Console.WriteLine(str);
}
}
}